<?php
/**
 * Handles all module architecture and third-party integration
 *
 * @package Concerto
 * @subpackage System
 * @author Jason Raede <jason@torchdm.com>
 */
namespace application\system;
use application\utilities\Utility;

class Modulator {
	
	/**
	 * Filters registered by modules
	 *
	 * @var array
	 */
	protected $registeredFilters = array();
	
	/**
	 * Functions registered by modules
	 *
	 * @var array
	 */
	protected $registeredFunctions = array();
	
	/**
	 * Admin panels registered by modules
	 *
	 * @var array
	 */
	public $registeredPanels = array();
	
	/**
	 * Data types registered by modules
	 *
	 * @var array
	 */
	public $registeredDataTypes = array();
	
	/**
	 * Scripts included by modules or datatypes, so they aren't included twice
	 *
	 * @var array
	 */
	protected $includedScripts = array();
	
	/**
	 * Any variables in modules that can be used outside of the module can be stored here
	 *
	 * @var array
	 */
	protected $globals = array();
	
	/**
	 * Common javascript library names and their include locations
	 *
	 * @var array
	 */
	protected $availableScripts = array(
		//'jquery'=>'https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js',
		'jquery'=>'http://concerto.torchdm.com/includes/third-party/jquery/jquery.min.js',
		//'jquery'=>'http://localhost:8888/site-development/concerto-includes/includes/third-party/jquery/jquery.min.js',
		//'jquery ui'=>'http://localhost:8888/site-development/concerto-includes/includes/third-party/jquery/jquery.ui.min.js',
		'google maps'=>'http://maps.googleapis.com/maps/api/js?sensor=false',
		//'jquery ui'=>'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js',
		'jquery ui'=>'http://concerto.torchdm.com/includes/third-party/jquery/jquery.ui.min.js',
		'mootools'=>'https://ajax.googleapis.com/ajax/libs/mootools/1.3.2/mootools-yui-compressed.js',
		'prototype'=>'https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js',
		'scriptaculous'=>'https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js',
		'swfobject'=>'https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js',
		'yahoo'=>'https://ajax.googleapis.com/ajax/libs/yui/3.3.0/build/yui/yui-min.js',
		'webfont'=>'https://ajax.googleapis.com/ajax/libs/webfont/1.0.22/webfont.js',
		'chrome frame'=>'https://ajax.googleapis.com/ajax/libs/chrome-frame/1.0.2/CFInstall.min.js',
		'dojo'=>'https://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js',
		'ext core'=>'https://ajax.googleapis.com/ajax/libs/ext-core/3.1.0/ext-core.js',
		'browser plus'=>'http://bp.yahooapis.com/2.4.21/browserplus-min.js'
	);
	
	/**
	 * Query vars that are allowed in the URL query string
	 *
	 * @var array
	 */	
	public $registeredQueryVars = array('action', 'display', 'page', 'level', 'date', 'time', 'tag', 'id', 'not_id', 'admin', 'status', 'order', 'order_dir', 'search', 'parent', 'child_of', 'alert', 'redirect', 'type', 'edit_tag', 'edit_group', 'interaction_id', 'search_mode', 'menu', 'delete_menu', 'year', 'month', 'action', 'file', 'field', 'fields', 'first_letter', 'method', 'grandchild_of', 'mode', 'edit', 'template', 'form', 'view', 'content_relation', 'content_relation_with', 'limit', 'handler', 'file', 'author', 'timestamp_greater_than', 'timestamp_less_than', 'level');
	
	
	/**
	 * Register an additional query variable
	 *
	 * @param string $var
	 */
	public function registerQueryVar($var) {
		$this->registeredQueryVars[] = $var;
	}
	
	/**
	 * Include a javascript either by name (if the script is in $availableScripts) or by location
	 * on the web
	 *
	 * @param string $script Name or location
	 */
	public function includeScript($script) {
		if(!in_array($script, $this->includedScripts)) {
			if($src = $this->availableScripts[$script]) {
				?><script type="text/javascript" src="<?=$src?>"></script><?php
			}
			else {
				?><script type="text/javascript" src="<?=$script?>"></script><?php
			}
			$this->includedScripts[] = $script;
		}	
	}
	
	/**
	 * Runs a value through all filters registered on that hook
	 *
	 * @param string $hook The hook name
	 * @param mixed $original The original value generated by Concerto
	 * @param array $args Optional arguments to pass to filters
	 * @return mixed The value after it has passed through all the filters
	 */
	public function runFilter($hook, $original, $args = null) {
		Utility::reportToConsole('FILTER: '.$hook);
		$value = $original;
		if(count($this->registeredFilters[$hook])) {
			foreach($this->registeredFilters[$hook] as $function) {
				$value = $function($value, $args);
			}
		}
		return $value;
	}
	
	/**
	 * Runs all functions registered on that hook
	 *
	 * @param string $hook The hook name
	 * @param array $args Optional arguments to pass to the functions
	 */	
	public function runFunction($function, $args = null) {
		Utility::reportToConsole('FUNCTION: '.$function);
		if(is_array($this->registeredFunctions[$function])) {
			foreach($this->registeredFunctions[$function] as $function) {
				$function($args);
			}
		}
	}
	
	/**
	 * Register a function on a hook
	 *
	 * @param string $hook
	 * @param string $function The function name
	 */
	public function registerFunction($hook, $function) {
		$this->registeredFunctions[$hook][] = $function;
	}
	
	/**
	 * Register a filter on a hook
	 *
	 * @param string $hook
	 * @param string $filter The filter function name
	 */
	public function registerFilter($hook, $filter) {
		$this->registeredFilters[$hook][] = $filter;
	}
	
	/**
	 * Register a panel for a module
	 *
	 * @param string $panel The panel name
	 * @param string $function The name of the function to run when that panel is viewed
	 */
	public function registerPanel($panel, $function) {
		$this->registeredPanels[$panel] = $function;
	}
	
	/**
	 * Register a data type
	 *
	 * @param string $dataTypeName The name of the data type (class name)
	 * @param string $location The location on the filesystem of the class
	 */
	public function registerDataType($dataTypeName, $location) {
		$this->registeredDataTypes[$dataTypeName] = $location;
	}
	
	/**
	 * Returns all registered data types
	 *
	 * @return array
	 */
	public function getRegisteredDataTypes() {
		return $this->registeredDataTypes;
	}
	
	/**
	 * Get the file location of a specific data type
	 *
	 * @param string $dataTypeName
	 * @return string
	 */
	public function getDataTypePath($dataTypeName) {
		return $this->registeredDataTypes[$dataTypeName];
	}
	
	/**
	 * @deprecated
	 */
	public function getPanelPath($panelName) {
		return $this->registeredPanels[$panelName];
	}
	
	/**
	 * Get an array of all registered data types
	 *
	 * @return array
	 */
	public function getDataTypeNames() {
		return array_keys($this->registeredDataTypes);
	}
	
	/**
	 * Check if a panel is registered
	 *
	 * @param string $panel
	 * @return bool
	 */
	public function panelExists($panel) {
		return $this->registeredPanels[$panel];
	}	
	
	/**
	 * @deprecated
	 */
	public function loadPanel($panel) {
		require $panel;
	}
	
	/**
	 * Include all module files of activated modules
	 */
	public function includeModules() {
		global $concerto;
		$modules = unserialize($concerto->getOption('activated_modules'));
		if(!$modules) $modules = array();
		if(count($modules)) {
			foreach($modules as $module) {
				if(file_exists(CN_DOCUMENT_ROOT.'modules/'.$module)) require_once CN_DOCUMENT_ROOT.'modules/'.$module;
			}
		}
		
	}
	
	/**
	 * Get a global variable
	 *
	 * @param string $var
	 * @return mixed
	 */
	public function getGlobal($var) {
		return $this->globals[$var];
	}
	
	/**
	 * Set a global variable
	 *
	 * @param string $var
	 * @param mixed $value
	 */
	public function setGlobal($var, $value) {
		$this->globals[$var] = $value;
	}
}
?>